package org.mv.mm.docs;

import java.awt.BorderLayout;
import java.util.Collection;
import java.util.Iterator;
import javax.swing.ActionMap;
import javax.swing.text.DefaultEditorKit;
import org.mv.mm.api.Doc;
import org.mv.mm.api.data.IDataProvider;
import org.mv.mm.common.ILinkedWindow;
import org.mv.mm.docs.nodes.DocNode;
import org.mv.mm.docs.nodes.FragmentRootNode;
import org.netbeans.api.settings.ConvertAsProperties;
import org.openide.explorer.ExplorerManager;
import org.openide.explorer.ExplorerUtils;
import org.openide.explorer.view.OutlineView;
import org.openide.nodes.Node;
import org.openide.util.Lookup;
import org.openide.util.LookupEvent;
import org.openide.util.LookupListener;
import org.openide.util.NbBundle;
import org.openide.util.lookup.AbstractLookup;
import org.openide.util.lookup.InstanceContent;
import org.openide.util.lookup.ProxyLookup;
import org.openide.windows.TopComponent;
import org.openide.windows.WindowManager;

/**
 * Top component displaying tree of fragments.
 */
@ConvertAsProperties(dtd = "-//org.mv.mm.docs//Fragments//EN",
autostore = false)
@TopComponent.Description(preferredID = "FragmentsTopComponent",
//iconBase="SET/PATH/TO/ICON/HERE", 
persistenceType = TopComponent.PERSISTENCE_NEVER)
@NbBundle.Messages({
  "CTL_FragmentsTopComponent=Fragment Window",
  "HINT_FragmentsTopComponent=This is a fragment window"
})
public final class FragmentsTopComponent extends TopComponent implements LookupListener, ExplorerManager.Provider {

  private ExplorerManager em = new ExplorerManager();
  private TopComponent tcOpenedFrom;
  private Lookup.Result<DocNode> docNodeResult = null;
  private Lookup.Result<Doc> docResult = null;
  private Lookup.Result<IDataProvider> providerResult = null;
  private Lookup.Result<Node> cNodeResult = null;
  private IDataProvider dataProvider = null;
  private Doc doc = null;
  private final InstanceContent content;
  private final ShowParentCookie showPar;

  public FragmentsTopComponent() {//TODO rozdělit na privátní metody, aby nebyl konstruktor tak dlouhý
    initComponents();
    setName(Bundle.CTL_FragmentsTopComponent());
    setToolTipText(Bundle.HINT_FragmentsTopComponent());

    setLayout(new BorderLayout());
    OutlineView ov = new OutlineView("Fragment title/working title");
    //BeanTreeView ov = new BeanTreeView();
    //ov.setPropertyColumns(
    //      "chapAuthor", "Author");

    add(ov, BorderLayout.CENTER);


    ActionMap map = getActionMap();
    map.put("delete", ExplorerUtils.actionDelete(em, true)); // NOI18N
    map.put(DefaultEditorKit.copyAction, ExplorerUtils.actionCopy(em)); // currently unused
    map.put(DefaultEditorKit.cutAction, ExplorerUtils.actionCut(em));
    map.put(DefaultEditorKit.pasteAction, ExplorerUtils.actionPaste(em));
    
    //Create a new instance of our dynamic object:
    content = new InstanceContent();
    showPar = new ShowParentCookie();
    /*
     * Add the ShowParentCookie to context, so the action to show the parent
     * window is active.
     */
    content.add(showPar);
    
    ProxyLookup lookup = new ProxyLookup(ExplorerUtils.createLookup(em, map), new AbstractLookup(content));
    //Add the dynamic object to the TopComponent Lookup:
    associateLookup(lookup);
  }

  /**
   * This method is called from within the constructor to initialize the form.
   * WARNING: Do NOT modify this code. The content of this method is always
   * regenerated by the Form Editor.
   */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 545, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 401, Short.MAX_VALUE)
        );
    }// </editor-fold>//GEN-END:initComponents

    // Variables declaration - do not modify//GEN-BEGIN:variables
    // End of variables declaration//GEN-END:variables
  @Override
  public void componentOpened() {
    tcOpenedFrom = WindowManager.getDefault().getRegistry().getActivated();

    docNodeResult = tcOpenedFrom.getLookup().lookupResult(DocNode.class);

    cNodeResult = tcOpenedFrom.getLookup().lookupResult(Node.class);
    cNodeResult.addLookupListener(this);

    docResult = tcOpenedFrom.getLookup().lookupResult(Doc.class);
    providerResult = tcOpenedFrom.getLookup().lookupResult(IDataProvider.class);

    docNodeResult.addLookupListener(this);
    docResult.addLookupListener(this);
    providerResult.addLookupListener(this);

    resultChanged(null);
  }

  @Override
  public void componentClosed() {
    docNodeResult.removeLookupListener(this);
    docResult.removeLookupListener(this);
    providerResult.removeLookupListener(this);
  }

  @Override
  protected void componentShowing() {
    super.componentShowing();
  }

  @Override
  protected void componentActivated() {
    ExplorerUtils.activateActions(em, true);
  }

  @Override
  protected void componentDeactivated() {
    ExplorerUtils.activateActions(em, false);
  }

  void writeProperties(java.util.Properties p) {
    // better to version settings since initial version as advocated at
    // http://wiki.apidesign.org/wiki/PropertyFiles
    p.setProperty("version", "1.0");
    // TODO store your settings
  }

  void readProperties(java.util.Properties p) {
    String version = p.getProperty("version");
    // TODO read your settings according to their version
  }

  @Override
  public ExplorerManager getExplorerManager() {
    return em;
  }

  @Override
  public void resultChanged(LookupEvent ev) {
    //Close this T.C., when the original one, from which this one is opened, has been closed.
    //if (allNodes.isEmpty()) {
    if (!this.tcOpenedFrom.isOpened()) {
      this.close();
    } else {
      //Get the data provider:
      Collection<? extends IDataProvider> allQueries = providerResult.allInstances();
      Iterator<? extends IDataProvider> it1 = allQueries.iterator();
      while (it1.hasNext()) {
        dataProvider = (IDataProvider) it1.next();
      }
      //Get the document:
      Collection<? extends Doc> allDocs = docResult.allInstances();
      Iterator<? extends Doc> it2 = allDocs.iterator();
      while (it2.hasNext()) {
        doc = (Doc) it2.next();

        String partOfName;
        if (doc.getTitle() == null || doc.getTitle().isEmpty()) {
          partOfName = doc.getWorkName();
        } else {
          partOfName = doc.getTitle();
        }
        setDisplayName("Content of " + partOfName);

      }
      //Get the node:
      Collection<? extends DocNode> allNodes = docNodeResult.allInstances();


      FragmentRootNode node = new FragmentRootNode(dataProvider, doc);
      em.setRootContext(node);
    }
  }
  
  private class ShowParentCookie implements ILinkedWindow {

    @Override
    public void showParent() {
      FragmentsTopComponent.this.tcOpenedFrom.requestActive();
    }
  }
}
